import React, { useState, useCallback, useEffect, useRef } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Alert, ScrollView, SafeAreaView, Image, TextInput, Modal, Dimensions, Platform, PermissionsAndroid, ActivityIndicator } from 'react-native';
import { useNavigation, useFocusEffect } from '@react-navigation/native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Icon from 'react-native-vector-icons/Ionicons';
import axios from 'axios';
import Geolocation from '@react-native-community/geolocation';
import { VictoryPie } from 'victory-native';
import DailyTasks from '../utils/DailyTasks';
import I18n from '../utils/i18n';

const OPENWEATHERMAP_API_KEY = '7cc11fd2631d425000068aadac3ea858';
const CACHE_EXPIRATION = 30 * 60 * 1000; // 30 minutes
const REFRESH_INTERVAL = 10 * 60 * 1000; // 10 minutes

const defaultWeatherInfo = {
    temp: 25,
    description: I18n.t('sunny'),
    icon: '01d',
    cityName: I18n.t('unknown_city')
};

const HomePage = () => {
    const [currentMood, setCurrentMood] = useState(null);
    const [moodDescription, setMoodDescription] = useState('');
    const [isProfileSet, setIsProfileSet] = useState(false);
    const [userName, setUserName] = useState('');
    const [moodStreak, setMoodStreak] = useState(0);
    const [weatherInfo, setWeatherInfo] = useState(defaultWeatherInfo);
    const [avatar, setAvatar] = useState(null);
    const [location, setLocation] = useState(null);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);
    const [showLocationInput, setShowLocationInput] = useState(false);
    const [manualLocation, setManualLocation] = useState('');
    const [isLoadingWeather, setIsLoadingWeather] = useState(true);
    const [recentMoods, setRecentMoods] = useState([]);
    const [dailyTip, setDailyTip] = useState('');
    const [showDailyTasks, setShowDailyTasks] = useState(false);
    const navigation = useNavigation();
    const refreshInterval = useRef(null);

    useEffect(() => {
        requestLocationPermission();
        return () => {
            if (refreshInterval.current) {
                clearInterval(refreshInterval.current);
            }
        };
    }, []);

    const requestLocationPermission = async () => {
        if (Platform.OS === 'ios') {
            getOneTimeLocation();
        } else {
            try {
                const granted = await PermissionsAndroid.request(
                    PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                    {
                        title: I18n.t('location_permissions'),
                        message: I18n.t('location_permissions_tip1'),
                        buttonNeutral: I18n.t('ask_later'),
                        buttonNegative: I18n.t('cancel'),
                        buttonPositive: I18n.t('ok'),
                    },
                );
                if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                    getOneTimeLocation();
                } else {
                    setError(I18n.t('location_permissions_tip2'));
                    setIsLoading(false);
                }
            } catch (err) {
                console.warn(err);
                setError(I18n.t('location_permissions_tip3'));
                setIsLoading(false);
            }
        }
    };

    const getOneTimeLocation = () => {
        Geolocation.getCurrentPosition(
            (position) => {
                setLocation(position.coords);
                setIsLoading(false);
            },
            (error) => {
                console.log(error.message);
                setError(I18n.t('location_permissions_tip4'));
                setIsLoading(false);
            },
            { enableHighAccuracy: false, timeout: 30000, maximumAge: 1000 }
        );
    };

    const loadData = useCallback(async () => {
        try {
            // Fetch daily quote from API
            try {
                const quoteResponse = await axios.get('https://v1.hitokoto.cn/');
                setDailyTip(quoteResponse.data.hitokoto);
            }catch (error){
                const tips = [
                    I18n.t('tips.one'),
                    I18n.t('tips.two'),
                    I18n.t('tips.three'),
                    I18n.t('tips.four'),
                    I18n.t('tips.five'),
                ];
                setDailyTip(tips[Math.floor(Math.random() * tips.length)]);
            }

            // Load user profile
            const savedUserName = await AsyncStorage.getItem('userName');
            const savedAvatar = await AsyncStorage.getItem('userAvatar');
            setUserName(savedUserName || '');
            setAvatar(savedAvatar);
            setIsProfileSet(!!savedUserName);

            // Load current mood
            const savedMood = await AsyncStorage.getItem('currentMood');
            if (savedMood) {
                const parsedMood = JSON.parse(savedMood);
                const moodDate = new Date(parsedMood.date);
                const today = new Date();

                if (moodDate.toDateString() === today.toDateString()) {
                    setCurrentMood(parsedMood.mood);
                    setMoodDescription(parsedMood.description);
                } else {
                    setCurrentMood(null);
                    setMoodDescription('');
                    await AsyncStorage.removeItem('currentMood');
                }
            }

            // Calculate mood streak
            const history = await AsyncStorage.getItem('moodHistory');
            if (history) {
                const moodHistory = JSON.parse(history);
                let streak = 0;
                const today = new Date().toDateString();
                for (let i = moodHistory.length - 1; i >= 0; i--) {
                    const entryDate = new Date(moodHistory[i].date).toDateString();
                    if (entryDate === today || (streak > 0 && isConsecutiveDay(entryDate, moodHistory[i+1].date))) {
                        streak++;
                    } else {
                        break;
                    }
                }
                setMoodStreak(streak);
                setRecentMoods(moodHistory.slice(-5).reverse()); // 获取最近5条记录
            }

            // Load weather info
            await loadWeatherInfo();

        } catch (error) {
            console.error('Error loading data:', error);
        } finally {
            setIsLoading(false);
        }
    }, [location, manualLocation]);

    const loadWeatherInfo = async () => {
        setIsLoadingWeather(true);
        try {
            const cachedData = await AsyncStorage.getItem('weatherCache');
            const cachedTimestamp = await AsyncStorage.getItem('weatherCacheTimestamp');

            if (cachedData && cachedTimestamp) {
                const parsedData = JSON.parse(cachedData);
                const timestamp = parseInt(cachedTimestamp);
                if (Date.now() - timestamp < CACHE_EXPIRATION) {
                    setWeatherInfo(parsedData);
                    setIsLoadingWeather(false);
                    return;
                }
            }

            let weatherResponse;
            if (location) {
                weatherResponse = await axios.get(
                    `https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&appid=${OPENWEATHERMAP_API_KEY}&units=metric`
                );
            } else if (manualLocation) {
                weatherResponse = await axios.get(
                    `https://api.openweathermap.org/data/2.5/weather?q=${manualLocation}&appid=${OPENWEATHERMAP_API_KEY}&units=metric`
                );
            }

            const weatherData = weatherResponse.data;
            const newWeatherInfo = {
                temp: Math.round(weatherData.main.temp),
                description: weatherData.weather[0].description,
                icon: weatherData.weather[0].icon,
                cityName: weatherData.name
            };
            setWeatherInfo(newWeatherInfo);

            // Cache the new weather data
            await AsyncStorage.setItem('weatherCache', JSON.stringify(newWeatherInfo));
            await AsyncStorage.setItem('weatherCacheTimestamp', Date.now().toString());
        } catch (error) {
            console.error('Error loading weather info:', error);
            // If loading fails, use default weather info or last successfully loaded info
        } finally {
            setIsLoadingWeather(false);
        }
    };

    useEffect(() => {
        const weatherRefreshInterval = setInterval(() => {
            loadWeatherInfo();
        }, REFRESH_INTERVAL);

        return () => clearInterval(weatherRefreshInterval);
    }, [location, manualLocation]);

    useFocusEffect(
        useCallback(() => {
            if (location || manualLocation) {
                loadData();
            }
        }, [location, manualLocation, loadData])
    );

    const handleManualLocationSubmit = () => {
        if (manualLocation) {
            setLocation(null); // Clear auto-detected location
            loadData();
            setShowLocationInput(false);
        }
    };

    const handleSetMood = () => {
        if (isProfileSet) {
            navigation.navigate('MoodSetting');
        } else {
            Alert.alert(I18n.t('MoodSetting_tips.title'), I18n.t('MoodSetting_tips.content'), [
                { text: I18n.t('MoodSetting_tips.cancel'), style: 'cancel' },
                { text: I18n.t('MoodSetting_tips.goto'), onPress: () => navigation.navigate('Profile') }
            ]);
        }
    };

    const getWeatherIcon = () => {
        const iconCode = weatherInfo.icon;
        switch (iconCode) {
            case '01d':
            case '01n':
                return 'sunny-outline';
            case '02d':
            case '02n':
            case '03d':
            case '03n':
                return 'partly-sunny-outline';
            case '04d':
            case '04n':
                return 'cloud-outline';
            case '09d':
            case '09n':
            case '10d':
            case '10n':
                return 'rainy-outline';
            case '11d':
            case '11n':
                return 'thunderstorm-outline';
            case '13d':
            case '13n':
                return 'snow-outline';
            default:
                return 'cloud-outline';
        }
    };

    const isConsecutiveDay = (date1, date2) => {
        const d1 = new Date(date1);
        const d2 = new Date(date2);
        const timeDiff = Math.abs(d2.getTime() - d1.getTime());
        return timeDiff <= 86400000 && d1.getDate() !== d2.getDate(); // 86400000 ms in a day
    };

    const renderMoodChart = () => {
        const moodCounts = recentMoods.reduce((acc, mood) => {
            acc[mood.mood.emoji] = (acc[mood.mood.emoji] || 0) + 1;
            return acc;
        }, {});

        const data = Object.entries(moodCounts).map(([emoji, count]) => ({
            x: emoji,
            y: count
        }));

        return (
            <View style={styles.chartContainer}>
                <Text style={styles.sectionTitle}>{I18n.t('recent_mood_overview')}</Text>
                <VictoryPie
                    data={data}
                    width={250}
                    height={250}
                    colorScale="qualitative"
                    labelRadius={({ innerRadius }) => innerRadius + 30}
                    radius={({ datum }) => 50 + datum.y * 20}
                    innerRadius={30}
                    style={{ labels: { fill: "black", fontSize: 20, fontWeight: "bold" } }}
                />
            </View>
        );
    };

    if (isLoading) {
        return (
            <View style={styles.loadingContainer}>
                <ActivityIndicator size="large" color="#0000ff" />
                <Text>{I18n.t('loading')}</Text>
            </View>
        );
    }

    return (
        <SafeAreaView style={styles.safeArea}>
            <ScrollView style={styles.scrollView}
                        contentContainerStyle={styles.scrollViewContent}
            >
                <View style={styles.header}>
                    <Image
                        source={{ uri: (avatar == null ? 'https://via.placeholder.com/150' : avatar)  }}
                        style={styles.avatar}
                    />
                    <Text style={styles.welcomeText}>{I18n.t('welcome.one')}, {userName || I18n.t('welcome.two')}!</Text>
                </View>

                <View style={styles.weatherContainer}>
                    <View style={styles.weatherInfo}>
                        <Icon name={getWeatherIcon()} size={50} color="#FFA500" />
                        <View>
                            <Text style={styles.dateText}>{new Date().toLocaleDateString()}</Text>
                            <Text style={styles.weatherText}>
                                {weatherInfo.cityName}, {weatherInfo.temp}°C, {weatherInfo.description}
                            </Text>
                            {isLoadingWeather && <Text style={styles.updatingText}>{I18n.t('updating_weather')}</Text>}
                        </View>
                    </View>
                    <TouchableOpacity
                        style={styles.changeLocationButton}
                        onPress={() => setShowLocationInput(true)}
                    >
                        <Icon name="location-outline" size={16} color="#4CAF50" />
                    </TouchableOpacity>
                </View>

                <View style={styles.tipContainer}>
                    <Icon name="bulb-outline" size={24} color="#FFD700" />
                    <Text style={styles.tipText}>{dailyTip}</Text>
                </View>

                {isProfileSet ? (
                    currentMood ? (
                        <View style={styles.moodContainer}>
                            <View style={styles.moodHeader}>
                                <Text style={styles.moodText}>{I18n.t('today_s_mood')}: {currentMood.emoji} {currentMood.label}</Text>
                                <TouchableOpacity onPress={handleSetMood}>
                                    <Icon name="create-outline" size={24} color="#4CAF50" />
                                </TouchableOpacity>
                            </View>
                            <Text style={styles.descriptionText}>{moodDescription}</Text>
                        </View>
                    ) : (
                        <TouchableOpacity style={styles.setMoodButton} onPress={handleSetMood}>
                            <Icon name="heart-outline" size={24} color="#fff" />
                            <Text style={styles.setMoodButtonText}>{I18n.t('set_today_s_mood')}</Text>
                        </TouchableOpacity>
                    )
                ) : (
                    <TouchableOpacity style={styles.setProfileButton} onPress={() => navigation.navigate('Profile')}>
                        <Icon name="person-add-outline" size={24} color="#fff" />
                        <Text style={styles.setProfileButtonText}>{I18n.t('set_personal_information')}</Text>
                    </TouchableOpacity>
                )}

                <View style={styles.streakContainer}>
                    <Icon name="flame-outline" size={24} color="#FF6347" />
                    <Text style={styles.streakText}>{I18n.t('moodStreak',{ count: moodStreak })}</Text>
                </View>

                {renderMoodChart()}

                <View style={styles.recentMoodsContainer}>
                    <Text style={styles.sectionTitle}>{I18n.t('recent_mood_records')}</Text>
                    {recentMoods.map((mood, index) => (
                        <View key={index} style={styles.recentMoodItem}>
                            <Text style={styles.recentMoodDate}>{new Date(mood.date).toLocaleDateString()}</Text>
                            <Text style={styles.recentMoodEmoji}>{mood.mood.emoji}</Text>
                            <Text style={styles.recentMoodDescription}>{mood.description}</Text>
                        </View>
                    ))}
                </View>

                <TouchableOpacity
                    style={styles.challengeButton}
                    onPress={() => setShowDailyTasks(true)}
                >
                    <Icon name="trophy-outline" size={24} color="#fff" />
                    <Text style={styles.challengeButtonText}>{I18n.t('today_s_small_task')}</Text>
                </TouchableOpacity>

                <TouchableOpacity
                    style={styles.historyButton}
                    onPress={() => navigation.navigate('MoodHistory')}
                >
                    <Icon name="bar-chart-outline" size={24} color="#fff" />
                    <Text style={styles.historyButtonText}>{I18n.t('view_mood_history')}</Text>
                </TouchableOpacity>

                <DailyTasks
                    isVisible={showDailyTasks}
                    onClose={() => setShowDailyTasks(false)}
                    currentMood={currentMood}
                />

                <Modal
                    visible={showLocationInput}
                    transparent={true}
                    animationType="slide"
                >
                    <View style={styles.modalContainer}>
                        <View style={styles.modalContent}>
                            <TextInput
                                style={styles.locationInput}
                                placeholder={I18n.t('enter_city_name')}
                                value={manualLocation}
                                onChangeText={setManualLocation}
                            />
                            <TouchableOpacity style={styles.submitButton} onPress={handleManualLocationSubmit}>
                                <Text style={styles.submitButtonText}>{I18n.t('Submit')}</Text>
                            </TouchableOpacity>
                            <TouchableOpacity style={styles.cancelButton} onPress={() => setShowLocationInput(false)}>
                                <Text style={styles.cancelButtonText}>{I18n.t('cancel')}</Text>
                            </TouchableOpacity>
                        </View>
                    </View>
                </Modal>
            </ScrollView>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    safeArea: {
        flex: 1,
        backgroundColor: '#f5f5f5',
    },
    scrollView: {
        flex: 1,
    },
    scrollViewContent: {
        padding: 20,
        paddingBottom: 30, // Add extra padding at the bottom
    },
    header: {
        flexDirection: 'row',
        alignItems: 'center',
        marginBottom: 20,
    },
    avatar: {
        width: 60,
        height: 60,
        borderRadius: 30,
        marginRight: 15,
    },
    welcomeText: {
        fontSize: 22,
        fontWeight: 'bold',
    },
    weatherContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        marginBottom: 20,
        backgroundColor: '#fff',
        padding: 15,
        borderRadius: 10,
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.1,
        shadowRadius: 4,
        elevation: 3,
    },
    weatherInfo: {
        flexDirection: 'row',
        alignItems: 'center',
    },
    dateText: {
        fontSize: 16,
        marginLeft: 10,
    },
    weatherText: {
        fontSize: 14,
        color: '#666',
        marginLeft: 10,
    },
    updatingText: {
        fontSize: 12,
        color: '#888',
        marginTop: 5,
    },
    changeLocationButton: {
        padding: 10,
    },
    tipContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        backgroundColor: '#FFF9E5',
        padding: 15,
        borderRadius: 10,
        marginBottom: 20,
    },
    tipText: {
        marginLeft: 10,
        fontSize: 16,
        color: '#333',
    },
    moodContainer: {
        backgroundColor: '#fff',
        padding: 20,
        borderRadius: 10,
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.1,
        shadowRadius: 4,
        elevation: 3,
        marginBottom: 20,
    },
    moodHeader: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        marginBottom: 10,
    },
    moodText: {
        fontSize: 20,
        fontWeight: 'bold',
    },
    descriptionText: {
        fontSize: 16,
    },
    setMoodButton: {
        backgroundColor: '#4CAF50',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        padding: 15,
        borderRadius: 10,
        marginBottom: 20,
    },
    setMoodButtonText: {
        color: 'white',
        fontSize: 18,
        marginLeft: 10,
    },
    setProfileButton: {
        backgroundColor: '#3498db',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        padding: 15,
        borderRadius: 10,
        marginBottom: 20,
    },
    setProfileButtonText: {
        color: 'white',
        fontSize: 18,
        marginLeft: 10,
    },
    streakContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        marginBottom: 20,
    },
    streakText: {
        fontSize: 16,
        marginLeft: 10,
        color: '#FF6347',
    },
    chartContainer: {
        alignItems: 'center',
        backgroundColor: '#fff',
        padding: 15,
        borderRadius: 10,
        marginBottom: 20,
    },
    sectionTitle: {
        fontSize: 18,
        fontWeight: 'bold',
        marginBottom: 10,
    },
    recentMoodsContainer: {
        backgroundColor: '#fff',
        padding: 15,
        borderRadius: 10,
        marginBottom: 20,
    },
    recentMoodItem: {
        flexDirection: 'row',
        alignItems: 'center',
        marginBottom: 10,
    },
    recentMoodDate: {
        width: 80,
        fontSize: 12,
    },
    recentMoodEmoji: {
        fontSize: 24,
        marginHorizontal: 10,
    },
    recentMoodDescription: {
        flex: 1,
        fontSize: 14,
    },
    challengeButton: {
        backgroundColor: '#FF6B6B',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        padding: 15,
        borderRadius: 10,
        marginBottom: 20,
    },
    challengeButtonText: {
        color: 'white',
        fontSize: 18,
        marginLeft: 10,
    },
    historyButton: {
        backgroundColor: '#3498db',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        padding: 15,
        borderRadius: 10,
    },
    historyButtonText: {
        color: 'white',
        fontSize: 18,
        marginLeft: 10,
    },
    modalContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
    },
    modalContent: {
        backgroundColor: 'white',
        padding: 20,
        borderRadius: 10,
        width: '80%',
    },
    locationInput: {
        borderWidth: 1,
        borderColor: '#ccc',
        borderRadius: 5,
        padding: 10,
        marginBottom: 10,
    },
    submitButton: {
        backgroundColor: '#4CAF50',
        padding: 10,
        borderRadius: 5,
        alignItems: 'center',
        marginBottom: 10,
    },
    submitButtonText: {
        color: 'white',
        fontSize: 16,
    },
    cancelButton: {
        backgroundColor: '#f44336',
        padding: 10,
        borderRadius: 5,
        alignItems: 'center',
    },
    cancelButtonText: {
        color: 'white',
        fontSize: 16,
    },
    loadingContainer: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
});

export default HomePage;
